namespace Microsoft.VisualStudio.EnterpriseTools.OperationDesigner
{
    using Microsoft.VisualStudio.VirtualTreeGrid;
    using System;
    using System.ComponentModel;

    public class ColumnTypeDescriptor : ICustomTypeDescriptor
    {
        private OperationDesignerBranch branch;
        private ColumnDescriptor[] columns;
        private int index;
        private object inner;
        private PropertyDescriptorCollection newProperties;

        public ColumnTypeDescriptor(OperationDesignerBranch branch, int index, ColumnDescriptor[] columns)
        {
            this.branch = branch;
            this.index = index;
            this.columns = columns;
            int options = 0;
            this.inner = branch.GetObject(index, 0, ObjectStyle.TrackingObject, ref options);
            if (this.inner == null)
            {
                throw new ArgumentException("index");
            }
        }

        public AttributeCollection GetAttributes()
        {
            return TypeDescriptor.GetAttributes(this.inner, false);
        }

        public virtual string GetClassName()
        {
            return TypeDescriptor.GetClassName(this.inner, false);
        }

        public virtual string GetComponentName()
        {
            return TypeDescriptor.GetComponentName(this.inner, false);
        }

        public TypeConverter GetConverter()
        {
            return TypeDescriptor.GetConverter(this.inner.GetType());
        }

        public EventDescriptor GetDefaultEvent()
        {
            return TypeDescriptor.GetDefaultEvent(this.inner, false);
        }

        public PropertyDescriptor GetDefaultProperty()
        {
            return TypeDescriptor.GetDefaultProperty(this.inner, false);
        }

        public object GetEditor(Type editorBaseType)
        {
            return TypeDescriptor.GetEditor(this.inner.GetType(), editorBaseType, false);
        }

        public EventDescriptorCollection GetEvents()
        {
            return TypeDescriptor.GetEvents(this.inner, false);
        }

        public EventDescriptorCollection GetEvents(Attribute[] attributes)
        {
            return TypeDescriptor.GetEvents(this.inner, attributes, false);
        }

        public PropertyDescriptorCollection GetProperties()
        {
            return this.NewProperties;
        }

        public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
        {
            return this.NewProperties;
        }

        public object GetPropertyOwner(PropertyDescriptor pd)
        {
            if (this.inner is ICustomTypeDescriptor)
            {
                return ((ICustomTypeDescriptor) this.inner).GetPropertyOwner(pd);
            }
            return this.inner;
        }

        protected object Inner
        {
            get
            {
                return this.inner;
            }
        }

        protected virtual PropertyDescriptorCollection NewProperties
        {
            get
            {
                if (this.newProperties == null)
                {
                    this.newProperties = new PropertyDescriptorCollection(new PropertyDescriptor[0]);
                    foreach (ColumnDescriptor descriptor in this.columns)
                    {
                        if (descriptor.GetValueSupported(this.inner) != OperationDesignerValueSupportedStates.Unsupported)
                        {
                            if (this.branch.ReadOnly)
                            {
                                this.newProperties.Add(new ReadOnlyPropertyDescriptor(descriptor));
                            }
                            else
                            {
                                this.newProperties.Add(descriptor);
                            }
                        }
                    }
                }
                return this.newProperties;
            }
        }

        protected virtual bool ReadOnly
        {
            get
            {
                return this.branch.ReadOnly;
            }
        }
    }
}

